練習タイムの記録表作成を、スマホだけで
私のいた水泳部では、練習時に計測した選手のタイムを毎回Excelにまとめ、選手にフィードバックするのがマネージャーの仕事でした。当時抱えていた、入力に手間がかかる・PCが必要になる・複数マネージャーによる共同同時入力が困難といった課題を解決したのがこのLINEのチャットボットです。練習タイムをLINEの対話形式でデータベースに記録し、保存されたデータを表形式(CSV)に出力することができます。
テキストだけじゃないUI
基本はチャットボットですが、テキスト以外の情報のやりとりもできます。LINE Messaging APIを活用することでボタンを表示させたり複雑な構造のデータを表示させたりできます。
またLINE Front-end Framework(LIFF)の機能を活用することでLINE上で簡単なWebアプリを動かすことができます。
こちらはLIFFを活用したメニュー情報入力用のUIです。
工夫点
クライアントアプリにタイムを文字列として読み込ませる
m:ss.00
(0:32.11など)の形式でCSVに出力すると、スマホで閲覧した際に小数点以下が丸められてしまいます。(0:32.00のようになる) またExcelで開くと表示形式が勝手にm:ss.0
(0:32.1など)に変換させられてしまいます。Excelの場合ならユーザー(マネージャー)に表示形式を変更してもらうようお願いすれば良いですが、そのオペレーションを維持できるか不安でした。したがってTiMでは m:ss.00
の形式(タイムの前に半角空白を置く)でタイムを出力するようにしています。こうすることでスマホやExcel上でもタイムは数値ではなく文字列として認識され、表示が崩れなくなりました。
CSVはBOM付きUTF-8で出力
一般的に使用されるBOMなしUTF-8では、CSVファイルを直接Excelで開いた際にASCII文字以外を正しく認識できません。ExcelはデフォルトでShift-JISとしてファイルを読み込むためです。一方でShift-JIS形式でCSVを出力すると、スマホのメールクライアント上でCSVファイルを開いた際に文字化けが発生します。試行錯誤の結果、UTF-8にBOMを付与することでいずれの環境でも文字化けが発生しないことに気づきました。
インメモリDBでユーザーのステートを保持
本来チャットボットはステートレスなものです。しかしチャットボット側がユーザーの現在の状態(=ユーザーが編集中の場所など)を各メッセージ受信時に知っておく必要がありました。通常のWebアプリであればセッションで管理をしますが、チャットボットでは同じ方法で実装できません。代わりにインメモリデータベースであるRedisにユーザーの状態を保持しておくことにしました。ユーザーのプロフィール情報などは既にリレーショナルデータベース上で管理してありましたが、状態情報はあえてそれとは切り離しました。状態情報は頻繁に書き換えが発生するため、インメモリデータベースの速度面での恩恵が受けられると考えたためです。
反省
コミットログを見ると当時のすさまじい開発状況が垣間見えます。テストやデバッグを知りませんでした。コードを書いたら本番環境にデプロイし、毎回人力でLINEからリクエストを送って意図どおりに動いているか確かめます。バグが発生すると大変です。怪しい変数をprint関数に渡し、本番環境で表示させるのを何度も繰り返していました。コミットメッセージもなんのために書くのか分かりませんでした。コミット履歴には目も当てられません。
初めて開発したWebアプリだったゆえ、そうした至らぬ点がいくつもありました。それらに気づく度にアプリをまるごと2~3回書き直しています。UIも何度も変わっています。振り返ると自分の成長が分かるプロジェクトでもあります。